#pragma once
#include "mysql.hpp"
#include "chat_session.hxx"
#include "chat_session-odb.hxx"
#include "mysql_chat_session_member.hpp"

namespace chat_server
{
    class ChatSessionTable
    {
    public:
        using ptr = std::shared_ptr<ChatSessionTable>;
        ChatSessionTable(const std::shared_ptr<odb::core::database> &db) : _db(db) {}
        // 添加聊天session
        bool insert(ChatSession &cs)
        {
            try
            {
                odb::transaction trans(_db->begin());
                _db->persist(cs);
                trans.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("新增会话失败 {}:{}！", cs.chat_session_name(), e.what());
                return false;
            }
            return true;
        }
        // 删除聊天session 删除session数据和sessionMember数据
        bool remove(const std::string &ssid)
        {
            try
            {
                typedef odb::query<ChatSession> query;
                typedef odb::query<ChatSessionMember> queryMem;
                odb::transaction trans(_db->begin());
                _db->erase_query<ChatSession>(query::chat_session_id == ssid);
                _db->erase_query<ChatSessionMember>(queryMem::session_id == ssid);
                trans.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("删除会话失败 {}:{}！", ssid, e.what());
                return false;
            }
            return true;
        }
        // 根据个人和好友id删除单聊session
        bool remove(const std::string &uid, const std::string &pid)
        {
            try
            {
                typedef odb::query<SingleChatSession> query;
                typedef odb::result<SingleChatSession> result;
                odb::transaction trans(_db->begin());
                // 指定要删除会话的好友id
                auto r = _db->query_one<SingleChatSession>(query::csm1::user_id == uid &&
                                                           query::csm2::user_id == pid &&
                                                           query::css::chat_session_type == ChatSessionType::SINGLE);
                // 获取session_id
                std::string cssid = r->chat_session_id;

                typedef odb::query<ChatSession> cquery;
                _db->erase_query<ChatSession>(cquery::chat_session_id == cssid);

                typedef odb::query<ChatSessionMember> mquery;
                _db->erase_query<ChatSessionMember>(mquery::session_id == cssid);
                trans.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("删除会话失败 {}-{}:{}！", uid, pid, e.what());
                return false;
            }
            return true;
        }
        // 通过会话ID获取会话信息
        std::shared_ptr<ChatSession> select(const std::string &ssid)
        {
            std::shared_ptr<ChatSession> res;
            try
            {
                odb::transaction trans(_db->begin());
                typedef odb::query<ChatSession> query;
                typedef odb::result<ChatSession> result;
                res.reset(_db->query_one<ChatSession>(query::chat_session_id == ssid));
                trans.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("通过会话ID获取会话信息失败 {}:{}！", ssid, e.what());
            }
            return res;
        }
        // 获取该用户的所有单聊信息
        std::vector<SingleChatSession> singleChatSession(const std::string &uid)
        {
            std::vector<SingleChatSession> res;
            try
            {
                odb::transaction trans(_db->begin());
                typedef odb::query<SingleChatSession> query;
                typedef odb::result<SingleChatSession> result;
                // 当前的uid是被申请者的用户ID
                result r(_db->query<SingleChatSession>(
                    query::css::chat_session_type == ChatSessionType::SINGLE &&
                    query::csm1::user_id == uid &&
                    query::csm2::user_id != query::csm1::user_id));
                for (auto i = r.begin(); i != r.end(); ++i)
                {
                    res.push_back(*i);
                }
                trans.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("获取用户 {} 的单聊会话失败:{}！", uid, e.what());
            }
            return res;
        }
        // 获取该用户的所有群聊信息
        std::vector<GroupChatSession> groupChatSession(const std::string &uid)
        {
            std::vector<GroupChatSession> res;
            try
            {
                odb::transaction trans(_db->begin());
                typedef odb::query<GroupChatSession> query;
                typedef odb::result<GroupChatSession> result;
                // 当前的uid是被申请者的用户ID
                result r(_db->query<GroupChatSession>(
                    query::css::chat_session_type == ChatSessionType::GROUP &&
                    query::csm::user_id == uid));
                for (result::iterator i(r.begin()); i != r.end(); ++i)
                {
                    res.push_back(*i);
                }
                trans.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("获取用户 {} 的群聊会话失败:{}！", uid, e.what());
            }
            return res;
        }

    private:
        std::shared_ptr<odb::core::database> _db;
    };
}